home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / Arch / AF / audio.c next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  4.0 KB  |  186 lines

  1. /* AF/audio.c
  2.     vi:ts=3 sw=3:
  3.  
  4. This code written by:
  5.  
  6. Andrew "Alf" Leahy                         email: alf@st.nepean.uws.edu.au
  7. University of Western Sydney - Nepean.
  8. Sydney, Australia.                         phone: (047) 360622 (work)
  9.  
  10.  
  11. Modified by Marc Espie to adjust to tracker 4.0 API.
  12.  
  13.  */
  14.  
  15. #include "defs.h"
  16. #include "extern.h"
  17. #include "/usr/local/include/AF/AFlib.h"
  18. ID("$Id: audio.c,v 4.2 1995/02/01 16:43:47 espie Exp $")
  19.  
  20. /* 0 external handset, 1 for internal speaker */
  21. #define SPEAKER 0
  22.      
  23. LOCAL int stereo, primary, secondary;
  24.  
  25. LOCAL char *buffer, *buffer_r;
  26. LOCAL int nbytes=0, nbytes_r=0, ssize;
  27.  
  28. LOCAL ATime t, t_r, act, act_r;
  29. LOCAL AC ac, ac_r;
  30. LOCAL AFAudioConn *aud, *aud_r;
  31.  
  32. int sample_sizes[] = {
  33.     1,    /* MU255 */
  34.     1,    /* ALAW */
  35.     2,    /* Linear PCM, 16 bits, -1.0 <= x < 1.0 */
  36.     2,    /* Linear PCM, 32 bits, -1.0 <= x < 1.0 */
  37.     1,    /* G.721, 64Kbps to/from 32Kbps. */
  38.     1,    /* G.723, 64Kbps to/from 32Kbps. */
  39.     0
  40. };
  41.  
  42. int open_audio(int f, int s)
  43. {
  44.     AFSetACAttributes attributes;
  45.     int srate, device;
  46.     unsigned int channels;
  47.     AEncodeType type;
  48.     char *server;
  49.  
  50.     device = SPEAKER;
  51.     attributes.preempt = Mix;
  52.     attributes.start_timeout = 0;
  53.     attributes.end_silence = 0;
  54.     attributes.play_gain = 0;
  55.     attributes.rec_gain =  0;
  56.  
  57.     if ((server = (char *) getenv("AUDIOFILE")) == NULL)
  58.         end_all("Error: AUDIOFILE unset");
  59.     else
  60.     {
  61.         server = (char *) getenv("AUDIOFILE");
  62.         if ((aud = AFOpenAudioConn( server )) == NULL)
  63.             end_all("Error: can't open connection");
  64.         ac = AFCreateAC(aud, device, ACPlayGain, &attributes);
  65.         srate = ac->device->playSampleFreq;
  66.         type = ac->device->playBufType;
  67.         channels = ac->device->playNchannels;
  68.         ssize = sample_sizes[type] * channels;
  69.  
  70.         if ((buffer = (char *)malloc(ssize * srate)) == NULL)
  71.             end_all("Couldn't allocate play buffer");
  72.  
  73.         t = AFGetTime(ac);
  74.     }
  75.  
  76.     stereo=s;
  77.  
  78.     if (stereo)
  79.     {
  80.         server = (char *) getenv("AUDIORIGHT");
  81.         if ((aud = AFOpenAudioConn(server)) == NULL)
  82.             end_all("Error: can't open connection");
  83.         ac_r = AFCreateAC(aud, device, ACPlayGain, &attributes);
  84.         srate = ac->device->playSampleFreq;
  85.         type = ac->device->playBufType;
  86.         channels = ac->device->playNchannels;
  87.         ssize = sample_sizes[type] * channels;
  88.  
  89.         if ((buffer_r = (char *)malloc(ssize * srate)) == NULL)
  90.             end_all("Couldn't allocate play buffer");
  91.         t_r = AFGetTime(ac_r);
  92.     }
  93.  
  94.     return srate;
  95. }
  96.  
  97. void set_mix(int percent)
  98. {
  99.     percent *= 256;
  100.     percent /= 100;
  101.     primary = percent;
  102.     secondary = 512 - percent;
  103. }
  104.  
  105. void set_synchro(int s)
  106. {
  107. }
  108.  
  109. int update_frequency()
  110. {
  111.     return 0;
  112. }
  113.  
  114. LOCAL unsigned int cvt(int ch)
  115. {
  116.     int mask;
  117.  
  118.     if (ch < 0)
  119.     {
  120.         ch = -ch;
  121.         mask = 0x7f;
  122.     }
  123.     else
  124.         mask = 0xff;
  125.  
  126.     if (ch < 32)        ch = 0xF0 | 15 - (ch / 2);
  127.     else if (ch < 96)   ch = 0xE0 | 15 - (ch - 32) / 4;
  128.     else if (ch < 224)  ch = 0xD0 | 15 - (ch - 96) / 8;
  129.     else if (ch < 480)  ch = 0xC0 | 15 - (ch - 224) / 16;
  130.     else if (ch < 992)  ch = 0xB0 | 15 - (ch - 480) / 32;
  131.     else if (ch < 2016) ch = 0xA0 | 15 - (ch - 992) / 64;
  132.     else if (ch < 4064) ch = 0x90 | 15 - (ch - 2016) / 128;
  133.     else if (ch < 8160) ch = 0x80 | 15 - (ch - 4064) /  256;
  134.     else ch = 0x80;
  135.  
  136.     return (mask & ch);
  137. }
  138.  
  139. void output_samples(int left, int right)
  140. {
  141.     if (stereo)
  142.         if (primary) /* mixing needed */
  143.         {
  144.             buffer[nbytes++] = cvt((left * primary + right * secondary) >>18);
  145.             buffer_r[nbytes_r++] = cvt((right * primary + left * secondary) >>18);
  146.         }
  147.         else /* no mixing */
  148.         {
  149.             buffer[nbytes++] = cvt(left >>10);
  150.             buffer_r[nbytes_r++] = cvt(right >>10);
  151.         }
  152.     else /* mono */
  153.         buffer[nbytes++] = cvt((left + right) >>10);
  154. }
  155.  
  156. void flush_buffer()
  157. {
  158.     act = AFPlaySamples(ac, t, nbytes, buffer);
  159.     t += nbytes/ssize;
  160.     nbytes = 0;
  161.  
  162.     if (stereo) 
  163.     {
  164.         act_r = AFPlaySamples(ac_r, t_r, nbytes_r, buffer_r);
  165.         t_r += nbytes_r/ssize;
  166.         nbytes_r = 0;
  167.     }
  168. }
  169.  
  170. void discard_buffer()
  171. {
  172. }
  173.  
  174. void close_audio()
  175. {
  176.     free(buffer);
  177.  
  178. /* Alf: I'm not sure whether these functions are needed
  179.         I think these are Seg Faulting... */
  180.  
  181.      (void) AFCloseAudioConn(aud);
  182.  
  183.     if (stereo)
  184.         (void) AFCloseAudioConn(aud_r);
  185. }
  186.